package cn.tedu.cgb2202.sk.admin.webapi.service;

import cn.tedu.cgb2202.sk.admin.service.IAdminService;
import cn.tedu.cgb2202.sk.admin.webapi.mapper.AdminMapper;
import cn.tedu.cgb2202.sk.common.ex.ServiceException;
import cn.tedu.cgb2202.sk.common.util.PasswordEncoder;
import cn.tedu.cgb2202.sk.common.web.State;
import cn.tedu.cgb2202.sk.pojo.dto.AdminAddNewDTO;
import cn.tedu.cgb2202.sk.pojo.dto.AdminLoginDTO;
import cn.tedu.cgb2202.sk.pojo.entity.Admin;
import cn.tedu.cgb2202.sk.pojo.vo.AdminSimpleVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;

/**
 * 2022.6.14
 * 胡然
 * 该类用于处理Admin业务逻辑层
 */
@Slf4j
@Service
public class AdminServiceImpl implements IAdminService {

    @Autowired
    private AdminMapper adminMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    /**
     * 2022.6.14
     * 胡然
     * 用于处理添加用户逻辑
     * @param adminAddNewDTO 用户填写的信息
     */
    @Override
    public void addNew(@Validated AdminAddNewDTO adminAddNewDTO) {
        log.debug("从客户端获取到用户提交信息: " + adminAddNewDTO);

        log.debug("用户查重开始");
        if (adminMapper.getByUsername(adminAddNewDTO.getUsername()) != null) {
            log.warn("用户名已存在,抛出异常");
            throw new ServiceException(State.ERR_ADMIN_NAME_DUPLICATE,
                    "注册用户失败,用户名已存在!");
        } else if (adminMapper.getByPhone(adminAddNewDTO.getPhone()) != null) {
            log.warn("手机号码已存在,抛出异常");
            throw new ServiceException(State.ERR_ADMIN_PHONE_DUPLICATE,
                    "注册用户失败,手机号码已被占用");
        } else if (adminMapper.getByEmail(adminAddNewDTO.getEmail()) != null) {
            log.warn("email已存在,抛出异常");
            throw new ServiceException(State.ERR_ADMIN_EMAIL_DUPLICATE,
                    "注册用户失败,邮箱已被占用");
        }

        log.debug("数据库查重结束,执行密码加密..");
        String password = adminAddNewDTO.getPassword();
        log.debug("加密前密码: " + password);
        String encodedPassword = passwordEncoder.encode(password);
        log.debug("加密后密码: " + encodedPassword);

        LocalDateTime now = LocalDateTime.now();

        Admin admin = new Admin();
        BeanUtils.copyProperties(adminAddNewDTO, admin);
        admin.setPassword(encodedPassword);
        admin.setIsEnable(1);
        admin.setLastLoginIp(null);
        admin.setLoginCount(0);
        admin.setGmtLastLogin(null);
        admin.setGmtCreate(now);
        admin.setGmtModified(now);
        log.debug("Admin数据: " + admin);

        int rows = adminMapper.insert(admin);
        if (rows != 1) {
            log.debug("插入数据失败,抛出异常");
            throw new ServiceException(State.ERR_INSERT,
                    "注册失败,服务器忙,请稍后重试!");
        }
    }

    /**
     * 2022.6.15
     * 胡然
     * 用于处理用户登录逻辑
     * @param adminLoginDTO 用户填写的信息
     * @return 返回用户的信息
     */
    @Override
    public AdminSimpleVO login(AdminLoginDTO adminLoginDTO) {
        log.debug("获取用户提交信息 >>" + adminLoginDTO);
        String userInfo = adminLoginDTO.getUserInfo();
        log.debug("判断用户输入的是手机号还是email");
        if (userInfo.contains("@")){
            log.debug("用户输入的是email");
            return checkInfo(adminMapper.getByEmail(userInfo),adminLoginDTO);
        }
        log.debug("用户输入的是手机号");
        return checkInfo(adminMapper.getByPhone(userInfo),adminLoginDTO);
    }

    /**
     * 2022.6.15
     * 胡然
     * 该方法负责处理对用户提供信息的检查
     * @param queryResult 数据库查询到的信息
     * @param adminLoginDTO 用户提供的信息
     * @return 返回用户的信息
     */
    private AdminSimpleVO checkInfo(AdminSimpleVO queryResult,AdminLoginDTO adminLoginDTO){
        if (queryResult==null){
            log.warn("未查询到数据,抛出异常");
            throw new ServiceException(State.ERR_ADMIN_NOT_FOUND,
                    "登录失败,用户不存在!");
        }

        if (queryResult.getIsEnable()==0){
            log.warn("查询到了数据,但是用户未启用,抛出异常");
            throw new ServiceException(State.ERR_ADMIN_NOT_ENABLE,
                    "登录失败,用户被禁用!");
        }
        String password = adminLoginDTO.getPassword();
        Boolean matches = passwordEncoder.matches(password, queryResult.getPassword());
        if (!matches){
            log.warn("用户正常,密码错误,抛出异常");
            throw new ServiceException(State.ERR_ADMIN_PASSWORD_NOT_MATCH,
                    "登录失败,密码错误!");
        }
        queryResult.setPassword(null);
        queryResult.setIsEnable(null);
        log.debug("正常登录..");
        return queryResult;
    }
}
